#include "simulatewidget.h"
#include "ui_simulatewidget.h"
#include "protocolparse.h"
#include <string>
#include <iostream>
#include <QMessageBox>
#include <memory>

SimulateWidget::SimulateWidget(QWidget *parent) :
    QWidget(parent)
{
#ifdef __WIN32__
    ui = new Ui::SimulateWidget;
    ui->setupUi(this);

    QStringList list_type;
    list_type << QObject::tr("up") << QObject::tr("upmirror") << QObject::tr("down") << QObject::tr("downmirror");
    ui->comboBoxType->addItems(list_type);
    ui->comboBoxType->setCurrentIndex(0);

    QStringList list_ui_type;
    list_ui_type << QObject::tr("all") << QObject::tr("interval") << QObject::tr("arrive");
    ui->comboBoxUitype->addItems(list_ui_type);
    ui->comboBoxUitype->setCurrentIndex(0);

    QStringList list_current_key;
    list_current_key << QObject::tr("tc1") << QObject::tr("tc2");
    ui->comboBoxKeyPosition->addItems(list_current_key);
    ui->comboBoxKeyPosition->setCurrentIndex(0);

    QStringList list_car_num;
    list_car_num << QObject::tr("1") << QObject::tr("2")<< QObject::tr("3") << QObject::tr("4")
                 << QObject::tr("5") << QObject::tr("6")<< QObject::tr("7") << QObject::tr("8");
    ui->comboBoxCarnum->addItems(list_car_num);
    ui->comboBoxCarnum->setCurrentIndex(0);

    QStringList list_door;
    list_door << QObject::tr("open") << "close";
    ui->comboBoxDoor->addItems(list_door);
    ui->comboBoxDoor->setCurrentIndex(0);

#endif
    m_data_simulate = NULL;
    m_test_show = NULL;
    m_interval_flag = true;
    m_skip_list_data = "";
    m_items_change_text = "";
}

SimulateWidget::~SimulateWidget()
{
    delete ui;
}

bool SimulateWidget::is_skip_id(int id)
{
    foreach (int index, m_data_simulate->skip_list)
    {
        if (index == id)
            return true;
    }
    return false;
}

void SimulateWidget::curr_id_add_one()
{
    m_data_simulate->curr_or_next_id++;

    while (is_skip_id(m_data_simulate->curr_or_next_id))
        m_data_simulate->curr_or_next_id++;

    if (m_data_simulate->curr_or_next_id == m_data_simulate->stop_id + 1)
        m_data_simulate->curr_or_next_id = m_data_simulate->start_id;
}

void SimulateWidget::curr_id_reduce_one()
{
    m_data_simulate->curr_or_next_id--;

    while (is_skip_id(m_data_simulate->curr_or_next_id))
        m_data_simulate->curr_or_next_id--;

    if (m_data_simulate->curr_or_next_id == m_data_simulate->stop_id - 1)
        m_data_simulate->curr_or_next_id = m_data_simulate->start_id;
}

void SimulateWidget::config_interval()
{
    m_data_simulate->ui_type = IntervalFlag;
    if (m_xml_type == Up)
    {
        m_data_simulate->file_path = "interval_1.xml";
    } else if (m_xml_type == UpMirror)
    {
        m_data_simulate->file_path = "interval_1_mirror.xml";
    } else if (m_xml_type == Down)
    {
        m_data_simulate->file_path = "interval_2.xml";
    } else if (m_xml_type == DownMirror)
    {
        m_data_simulate->file_path = "interval_2_mirror.xml";
    }
}

void SimulateWidget::config_intervalall()
{
    m_data_simulate->ui_type = IntervalAllFlag;
    if (m_xml_type == Up)
    {
        m_data_simulate->file_path = QString("intervalall_1.xml");
    } else if (m_xml_type == UpMirror)
    {
        m_data_simulate->file_path = QString("intervalall_1_mirror.xml");
    } else if (m_xml_type == Down)
    {
        m_data_simulate->file_path = QString("intervalall_2.xml");
    } else if (m_xml_type == DownMirror)
    {
        m_data_simulate->file_path = QString("intervalall_2_mirror.xml");
    }
}

void SimulateWidget::config_arriveall()
{
    m_data_simulate->ui_type = ArriveAllFlag;
    if (m_xml_type == Up)
    {
        m_data_simulate->file_path = QString("arriveall_1.xml");
    } else if (m_xml_type == UpMirror)
    {
        m_data_simulate->file_path = QString("arriveal_1_mirror.xml");
    } else if (m_xml_type == Down)
    {
        m_data_simulate->file_path = QString("arriveall_2.xml");
    } else if (m_xml_type == DownMirror)
    {
        m_data_simulate->file_path = QString("arriveall_2_mirror.xml");
    }
}

void SimulateWidget::config_arrive()
{
    m_data_simulate->ui_type = ArriveFlag;
    if (m_xml_type == Up)
        m_data_simulate->file_path = QString("arrive_1.xml");

    else if (m_xml_type == UpMirror)
        m_data_simulate->file_path = QString("arrive_1_%1_mirror.xml").arg(m_data_simulate->curr_or_next_id);

    else if (m_xml_type == Down)
        m_data_simulate->file_path = QString("arrive_2.xml");

    else if (m_xml_type == DownMirror)
        m_data_simulate->file_path = QString("arrive_2_mirror.xml");
}

void SimulateWidget::config_all()
{
    m_data_simulate->ui_type = AllFlag;
    if (m_xml_type == Up)
    {
        m_data_simulate->file_path = "all_1.xml";
        curr_id_add_one();
    } else if (m_xml_type == UpMirror)
    {
        m_data_simulate->file_path = "all_1_mirror.xml";
        curr_id_add_one();
    } else if (m_xml_type == Down)
    {
        m_data_simulate->file_path = "all_2.xml";
        curr_id_reduce_one();
    } else if (m_xml_type == DownMirror)
    {
        m_data_simulate->file_path = "all_2_mirror.xml";
        curr_id_reduce_one();
    }
}

void SimulateWidget::simulate_timeout()
{
    m_test_show->show_file(m_data_simulate->file_path, (void *)m_data_simulate);

    //测试语言后缀,如：先将门隔离从图片修改成background_en.png进行测试，注释下面的自动报站,界面改成到站图可观察到小火车不会重新播放
//    if (m_data_simulate->suffix == "")
//        m_data_simulate->suffix = "en";
//    else
//        m_data_simulate->suffix = "";


    //测试items_change差异化显示
//    if (m_data_simulate->items_change.size() != 0)
//    {
//        if (m_data_simulate->items_change["single2"].content == "aaaaaa")
//            m_data_simulate->items_change["single2"].content = "bbbbbb";
//        else
//            m_data_simulate->items_change["single2"].content = "aaaaaa";
//    }


//    自动报站
    if (m_data_simulate->ui_type == AllFlag)
    {
        if (m_interval_flag)
            config_interval();
        else
            config_arrive();

    } else if (m_data_simulate->ui_type == IntervalFlag)
    {
        config_arrive();

    } else if (m_data_simulate->ui_type == ArriveFlag)
    {
        config_all();
    }
}

void SimulateWidget::add_id_combox()
{
#ifdef __WIN32__
    QStringList list_current_id;
    for (int i = 1; i <= myapp::mDynamicMapParam->m_station_total; i++)
        list_current_id.push_back(QString("%1").arg(i));

    ui->comboBoxCurrentId->addItems(list_current_id);
    ui->comboBoxCurrentId->setCurrentIndex(0);

    ui->comboBoxStartid->addItems(list_current_id);
    ui->comboBoxStartid->setCurrentIndex(0);

    ui->comboBoxStopid->addItems(list_current_id);
    ui->comboBoxStopid->setCurrentIndex(myapp::mDynamicMapParam->m_station_total - 1);
#endif
}

//void SimulateWidget::simulate_find_pic(QString img_path)
//{
//#ifdef __WIN32__
//    DynamicMapManageWindow *find_pic_show = new DynamicMapManageWindow();
//    QString xml_path = QString("%1/res/xml/").arg(myapp::mDynamicMapParam->m_project_path);

//    find_pic_show->set_path(xml_path, img_path);

//    ProtocolData *simulate_find_pic = new ProtocolData;

//    find_pic_show->show_file("welcome.xml", NULL);

//    QStringList ui_type_list = {AllFlag, IntervalFlag, ArriveFlag};
//    foreach (QString ui_type, ui_type_list)
//    {
//        simulate_find_pic->ui_type = ui_type;

//        for (int i = 1; i <= myapp::mDynamicMapParam->m_station_total; i++)
//        {
//            simulate_find_pic->curr_or_next_id = i;

//            if (simulate_find_pic->ui_type == "arrive")
//                simulate_find_pic->file_path = QString("%1_1_%2.xml").arg(simulate_find_pic->ui_type).arg(simulate_find_pic->curr_or_next_id);
//            else
//                simulate_find_pic->file_path = QString("%1_1.xml").arg(simulate_find_pic->ui_type);
//            simulate_find_pic->start_id = 1;
//            simulate_find_pic->stop_id = myapp::mDynamicMapParam->m_station_total;

//            if (simulate_find_pic->curr_or_next_id % 2 == 1)
//            {
//                simulate_find_pic->door_status = DOOR_OPEN;
//                simulate_find_pic->key_position = 1;
//            }
//            else
//            {
//                simulate_find_pic->door_status = DOOR_CLOSE;
//                simulate_find_pic->key_position = 2;
//            }
//            simulate_find_pic->car_number = i%7 == 0 ? 1 : i%7;

//            find_pic_show->show_file(simulate_find_pic->file_path, (void *)simulate_find_pic);
//        }
//    }
//    delete find_pic_show;

//    //小火车遮盖模拟的时候涉及不到单独去找
//    myapp::find_file(img_path, "car_left_1");
//    myapp::find_file(img_path, "car_left_2");
//    myapp::find_file(img_path, "car_left_3");
//    myapp::find_file(img_path, "car_left_4");
//    myapp::find_file(img_path, "car_left_5");
//    myapp::find_file(img_path, "car_left_6");
//    myapp::find_file(img_path, "car_right_1");
//    myapp::find_file(img_path, "car_right_2");
//    myapp::find_file(img_path, "car_right_3");
//    myapp::find_file(img_path, "car_right_4");
//    myapp::find_file(img_path, "car_right_5");
//    myapp::find_file(img_path, "car_right_6");
//#endif
//}

void SimulateWidget::get_items_change()
{
    if (m_items_change_text == "")
        return;
    std::string jsonStr = m_items_change_text.toStdString();

    bool res;
    JSONCPP_STRING errs;
    Json::Value root;
    Json::CharReaderBuilder readerBuilder;
    std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
    res = jsonReader->parse(jsonStr.c_str(), jsonStr.c_str()+jsonStr.length(), &root, &errs);

    if (!res || !errs.empty())
         LOG_QDEBUG << "parse json error, errs:" << errs.c_str();

    if (CheckJsonValueType(root, "items_change", Json::objectValue))
    {
        const Json::Value changeObj = root["items_change"];

        Json::Value::Members subMembers;
        subMembers = changeObj.getMemberNames();

        for (std::vector<std::string>::iterator it = subMembers.begin(); it != subMembers.end(); ++it)
        {
            if (CheckJsonValueType(changeObj, *it, Json::objectValue))
            {
                const Json::Value itemObj = changeObj[*it];

                change_property item;

                if (CheckJsonValueType(itemObj, "x", Json::intValue))
                {
                    item.x = itemObj["x"].asInt();
                }
                if (CheckJsonValueType(itemObj, "y", Json::intValue))
                {
                    item.y = itemObj["y"].asInt();
                }
                if (CheckJsonValueType(itemObj, "w", Json::intValue))
                {
                    item.w = itemObj["w"].asInt();
                }
                if (CheckJsonValueType(itemObj, "h", Json::intValue))
                {
                    item.h = itemObj["h"].asInt();
                }
                if (CheckJsonValueType(itemObj, "content", Json::stringValue))
                {
                    item.content = QString::fromStdString(itemObj["content"].asString());
                }
                m_data_simulate->items_change[QString::fromStdString(*it)] = item;
            }
        }
    }
}

void SimulateWidget::simulate_show_init(int all_num, XmlType type)
{
    m_test_show = new DynamicMapManageWindow();
    m_data_simulate = new ProtocolData;
    m_all_station_num = all_num;
    m_xml_type = type;

#ifdef __WIN32__

    m_auto_flag = ui->checkBoxAutoMinual->isChecked();
    m_interval_flag = ui->checkBoxShowInterval->isChecked();
    m_interval_time = ui->lineEdit->text().toInt();
    m_skip_list_data = ui->lineEditSkipList->text();
    m_items_change_text = ui->textEdit->toPlainText();

    QString xml_path = QString("%1/xml/").arg(myapp::mDynamicMapParam->m_project_path);

    QString res_path = QString("%1/img/").arg(myapp::mDynamicMapParam->m_project_path);

    m_test_show->set_path(xml_path, res_path);

    m_data_simulate->suffix = "";
//    for (int i = 0; i < m_all_station_num; i++)
//        m_data_simulate->eta_list.push_back(2);

    if (m_skip_list_data != "")
    {
        QStringList list = m_skip_list_data.split(",");
        for (int i = 0; i < list.size(); i++)
        {
            if (myapp::isDigitStr(list.at(i)))
                m_data_simulate->skip_list.append(list.at(i).toInt());
        }
    }

    get_items_change();

    m_data_simulate->curr_or_next_id = ui->comboBoxCurrentId->currentText().toInt();
    m_data_simulate->start_id = ui->comboBoxStartid->currentText().toInt();
    m_data_simulate->stop_id = ui->comboBoxStopid->currentText().toInt();
    if (m_xml_type == Up || m_xml_type == UpMirror)
    {
        if (m_data_simulate->start_id >= m_data_simulate->stop_id)
        {
            QMessageBox::warning(this, QObject::tr("error"), QObject::tr("type up do not allow start_id <= stop_id"));
            return;
        }
        if (m_data_simulate->curr_or_next_id < m_data_simulate->start_id || m_data_simulate->curr_or_next_id > m_data_simulate->stop_id)
        {
            QMessageBox::warning(this, QObject::tr("error"), QObject::tr("curr_or_next_id error"));
            return;
        }
    } else
    {
        if (m_data_simulate->start_id <= m_data_simulate->stop_id)
        {
            QMessageBox::warning(this, QObject::tr("error"), QObject::tr("type down do not allow start_id >= stop_id"));
            return;
        }
        if (m_data_simulate->curr_or_next_id < m_data_simulate->stop_id || m_data_simulate->curr_or_next_id > m_data_simulate->start_id)
        {
            QMessageBox::warning(this, QObject::tr("error"), QObject::tr("curr_or_next_id error"));
            return;
        }
    }

    m_data_simulate->car_number = ui->comboBoxCarnum->currentText().toInt();
    if (ui->comboBoxDoor->currentText() == "open")
        m_data_simulate->door_status = DOOR_OPEN;
    if (ui->comboBoxDoor->currentText() == "close")
        m_data_simulate->door_status = DOOR_CLOSE;
    if (ui->comboBoxKeyPosition->currentText() == "tc1")
        m_data_simulate->key_position = 1;
    if (ui->comboBoxKeyPosition->currentText() == "tc2")
        m_data_simulate->key_position = 2;
    m_data_simulate->ui_type = ui->comboBoxUitype->currentText();

#else
    m_auto_flag = true;
    m_data_simulate->curr_or_next_id = 1;
    m_data_simulate->start_id = 1;
    m_data_simulate->stop_id = all_num;
    m_data_simulate->car_number = 1;
    m_data_simulate->door_status = DOOR_OPEN;
    m_data_simulate->key_position = 1;
    m_interval_time = 6000;
    m_data_simulate->ui_type = AllFlag;
    m_data_simulate->suffix = "en";
//    for (int i = 0; i < m_all_station_num; i++)
//        m_data_simulate->eta_list.push_back(2);

//    m_data_simulate->skip_list.append(3);

#endif
    if (m_xml_type == Up)
    {
#ifdef __WIN32__
        if (myapp::mDynamicMapParam->mMapObjectShow.size() < 15)
            m_data_simulate->file_path = QString("%1_1.xml").arg(m_data_simulate->ui_type);
        else
#endif
            if (m_data_simulate->ui_type == "arrive")
                m_data_simulate->file_path = QString("%1_1_%2.xml").arg(m_data_simulate->ui_type).arg(m_data_simulate->curr_or_next_id);
            else
                m_data_simulate->file_path = QString("%1_1.xml").arg(m_data_simulate->ui_type);

    } else if (m_xml_type == UpMirror)
    {
#ifdef __WIN32__
        if (myapp::mDynamicMapParam->mMapObjectShow.size() < 15)
            m_data_simulate->file_path = QString("%1_1_mirror.xml").arg(m_data_simulate->ui_type);
        else
#endif
            if (m_data_simulate->ui_type == "arrive")
                m_data_simulate->file_path = QString("%1_1_%2_mirror.xml").arg(m_data_simulate->ui_type).arg(m_data_simulate->curr_or_next_id);
            else
                m_data_simulate->file_path = QString("%1_1_mirror.xml").arg(m_data_simulate->ui_type);

    } else if (m_xml_type == Down)
    {
#ifdef __WIN32__
        if (myapp::mDynamicMapParam->mMapObjectShow.size() < 15)
            m_data_simulate->file_path = QString("%1_2.xml").arg(m_data_simulate->ui_type);
        else
#endif
            if (m_data_simulate->ui_type == "arrive")
                m_data_simulate->file_path = QString("%1_2_%2.xml").arg(m_data_simulate->ui_type).arg(m_data_simulate->curr_or_next_id);
            else
                m_data_simulate->file_path = QString("%1_2.xml").arg(m_data_simulate->ui_type);
#ifdef __linux__
        m_data_simulate->start_id = all_num;
        m_data_simulate->stop_id = 1;
        m_data_simulate->curr_or_next_id = all_num;
#endif

    } else if (m_xml_type == DownMirror)
    {
#ifdef __WIN32__
        if (myapp::mDynamicMapParam->mMapObjectShow.size() < 15)
            m_data_simulate->file_path = QString("%1_2_mirror.xml").arg(m_data_simulate->ui_type);
        else
#endif
            if (m_data_simulate->ui_type == "arrive")
                m_data_simulate->file_path = QString("%1_2_%2_mirror.xml").arg(m_data_simulate->ui_type).arg(m_data_simulate->curr_or_next_id);
            else
                m_data_simulate->file_path = QString("%1_2_mirror.xml").arg(m_data_simulate->ui_type);
#ifdef __linux__
        m_data_simulate->start_id = all_num;
        m_data_simulate->stop_id = 1;
        m_data_simulate->curr_or_next_id = all_num;
#endif
    } else {}

    if (m_auto_flag)
    {
        m_test_show->show_file("welcome.xml", NULL);

        connect(&m_simulate_timer, &QTimer::timeout, this, &SimulateWidget::simulate_timeout);
        m_simulate_timer.start(m_interval_time);
#ifdef __WIN32__
        ui->pushButtonStart->setText(tr("pause"));
#endif
    } else
    {
        m_test_show->show_file(m_data_simulate->file_path, (void *)m_data_simulate);
    }
}

void SimulateWidget::on_pushButtonStart_clicked()
{
    if (m_simulate_timer.isActive() && m_test_show && m_data_simulate)
    {
        m_simulate_timer.stop();
        ui->pushButtonStart->setText(tr("continue"));
        return;
    }

    if (!m_simulate_timer.isActive() && m_test_show && m_data_simulate)
    {
        m_simulate_timer.start();
        ui->pushButtonStart->setText(tr("pause"));
        return;
    }

    //防止重复开始
    on_pushButtonStop_clicked();

    XmlType type = Up;

    if (ui->comboBoxType->currentText() == "down")
        type = Down;
    else if (ui->comboBoxType->currentText() == "downmirror")
        type = DownMirror;
    else if (ui->comboBoxType->currentText() == "upmirror")
        type = UpMirror;

#ifdef __WIN32__
    simulate_show_init(myapp::mDynamicMapParam->m_station_total, type);
#endif
}

void SimulateWidget::on_pushButtonStop_clicked()
{
    if (m_simulate_timer.isActive())
        m_simulate_timer.stop();
    //断开信号连接防止重复connect

    disconnect(&m_simulate_timer, 0, this, 0);

    if (m_data_simulate)
    {
        delete m_data_simulate;
        m_data_simulate = NULL;
    }
    if (m_test_show)
    {
        delete m_test_show;
        m_test_show = NULL;
    }

    ui->pushButtonStart->setText(tr("start"));
}

#ifdef __WIN32__
void SimulateWidget::on_comboBoxType_currentIndexChanged(const QString &arg1)
{
    if (arg1 == "down" || arg1 == "downmirror")
    {
        ui->comboBoxStartid->setCurrentIndex(myapp::mDynamicMapParam->m_station_total - 1);
        ui->comboBoxStopid->setCurrentIndex(0);
    }
    else
    {
        ui->comboBoxStartid->setCurrentIndex(0);
        ui->comboBoxStopid->setCurrentIndex(myapp::mDynamicMapParam->m_station_total - 1);
    }
    ui->comboBoxCurrentId->setCurrentText(ui->comboBoxStartid->currentText());
}
#endif

